/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.escom.healthlc.controller;

import com.escom.healthlc.business.HospitalBusiness;
import com.escom.healthlc.entidad.HospitalVO;
import com.escom.healthlc.utils.Constantes;
import com.escom.healthlc.utils.LazySorterHospital;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author LAURA
 */
@ManagedBean(name = "HospitalController")
@ViewScoped
public class HospitalController {

    private static final Logger logger = LoggerFactory.getLogger(HospitalController.class);

    private List<HospitalVO> retrieveHospital;
    private HospitalVO selectedHospital;
    private HospitalVO createHospital;
    private HospitalVO hospitalCurrent;
    private LazyDataModel<HospitalVO> modelHospital;
    private boolean renderPanelAlta;
    private boolean renderPanelConsulta;
    private boolean pageComplete;

    @ManagedProperty("#{HospitalBusiness}")
    private HospitalBusiness hospitalBusiness;

    public HospitalController() {
    }

    @PostConstruct
    private void initHospitalController() {
        executeLimpiarObejects(null);
    }

    public void executeCrearHospital(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        hospitalBusiness.crearHospital(createHospital);
        int estado = hospitalBusiness.getEstado();
        String messageEstado = hospitalBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }

        executeLimpiarObejects(acEvt);
    }

    public void executeConsultarHospital(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        retrieveHospital = hospitalBusiness.obtenerHospital();
        logger.debug("Size {}", retrieveHospital.size());

        if (retrieveHospital == null) {
            retrieveHospital = new ArrayList<HospitalVO>();
        }
        modelHospital = crearLazyModelHospital();
        int estado = hospitalBusiness.getEstado();
        String messageEstado = hospitalBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeChangeToRetrieve();
    }

    public void executeActualizarHospital(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        hospitalBusiness.actualizarHospital(selectedHospital);
        int estado = hospitalBusiness.getEstado();
        String messageEstado = hospitalBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObejects(acEvt);
    }

    public void executeEliminarHospital(ActionEvent acEvt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        FacesMessage facesMessage;
        hospitalBusiness.eliminarHospital(selectedHospital);
        int estado = hospitalBusiness.getEstado();
        String messageEstado = hospitalBusiness.getMessageEstado();
        switch (estado) {
            case Constantes.SIN_ERROR:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
            case Constantes.ERROR_BASE_DATOS:
                facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, Constantes.MESSAGE_TITLE, messageEstado);
                facesContext.addMessage(null, facesMessage);
                break;
        }
        executeLimpiarObejects(acEvt);
    }

    private LazyDataModel<HospitalVO> crearLazyModelHospital() {
        LazyDataModel<HospitalVO> lazyDataReturn = new LazyDataModel<HospitalVO>() {
            List<HospitalVO> datasource = retrieveHospital;

            @Override
            public HospitalVO getRowData(String rowKey) {
                for (HospitalVO hospital : datasource) {
                    if (hospital.getHospital().equals(rowKey)) {
                        return hospital;
                    }
                }
                return null;
            }

            @Override
            public List<HospitalVO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
                List<HospitalVO> data = new ArrayList<>();

                //filter  
                for (HospitalVO hospital : datasource) {
                    boolean match = true;
                    for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                        try {
                            String filterProperty = it.next();
                            Field field;
                            String filterValue = "";
                            String fieldValue;
                            field = hospital.getClass().getDeclaredField(filterProperty);
                            field.setAccessible(true);
                            filterValue = filters.get(filterProperty);
                            fieldValue = String.valueOf(field.get(hospital));

                            if (filterValue == null || fieldValue.contains(filterValue)) {
                                match = true;
                            } else {
                                match = false;
                                break;
                            }
                        } catch (Exception e) {
                            match = false;
                        }
                    }

                    if (match) {
                        data.add(hospital);
                    }
                }

//                sort  
                if (sortField != null) {
                    Collections.sort(data, new LazySorterHospital(sortField, sortOrder));
                }
                if (sortField == null) {
                    sortField = "defaultSortField";
                }
                //rowCount  
                int dataSize = data.size();
                this.setRowCount(dataSize);

                //paginate  
                if (dataSize > pageSize) {
                    try {
                        return data.subList(first, first + pageSize);
                    } catch (IndexOutOfBoundsException e) {
                        return data.subList(first, first + (dataSize % pageSize));
                    }
                } else {
                    return data;
                }
            }

            @Override
            public Object getRowKey(HospitalVO t) {
                return t.getIdHospital();
            }
        };
        return lazyDataReturn;
    }

    public void executeLimpiarObejects(ActionEvent acEvt) {
        retrieveHospital = new ArrayList<>();
        createHospital = new HospitalVO();
        renderPanelAlta = false;
        renderPanelConsulta = false;
    }

    public void executeChangeToCreate() {
        renderPanelAlta = true;
        renderPanelConsulta = false;
    }

    public void executeChangeToRetrieve() {
        renderPanelAlta = false;
        renderPanelConsulta = true;
    }

    public boolean isRenderPanelAlta() {
        return renderPanelAlta;
    }

    public void setRenderPanelAlta(boolean renderPanelAlta) {
        this.renderPanelAlta = renderPanelAlta;
    }

    public boolean isRenderPanelConsulta() {
        return renderPanelConsulta;
    }

    public void setRenderPanelConsulta(boolean renderPanelConsulta) {
        this.renderPanelConsulta = renderPanelConsulta;
    }

    public HospitalVO getSelectedHospital() {
        return selectedHospital;
    }

    public void setSelectedHospital(HospitalVO selectedHospital) {
        this.selectedHospital = selectedHospital;
    }

    public HospitalVO getCreateHospital() {
        return createHospital;
    }

    public void setCreateHospital(HospitalVO createHospital) {
        this.createHospital = createHospital;
    }

    public LazyDataModel<HospitalVO> getModelHospital() {
        return modelHospital;
    }

    public void setModelHospital(LazyDataModel<HospitalVO> modelHospital) {
        this.modelHospital = modelHospital;
    }

    public HospitalBusiness getHospitalBusiness() {
        return hospitalBusiness;
    }

    public void setHospitalBusiness(HospitalBusiness hospitalBusiness) {
        this.hospitalBusiness = hospitalBusiness;
    }

}
